import permissionCheckResolveDecorate from '@kuiper/auth/dist/server/lib/permissionCheckResolveDecorate';
import { dealWithBalance } from '../../plugins/billing';
import errorCodesBuilder from '../../helpers/errorCodesBuilder';
import {
	VUL_TYPE_MAP,
	SSL_CATEGORY_KEY_LABEL_MAP,
	SECURITY_EVENT_TYPE_MAP,
	WARNING_CATEGORY_KEY_LABEL_MAP,
} from '../../../common/constants';

const errorCodes = errorCodesBuilder('自定义监测任务处理失败');

const detailBuilder = ({ job, taskType, taskSettings }) => {
	const vulType = taskSettings?.alert?.vulType || [];
	const vul0 = taskSettings?.collect?.vul0;
	let vulTxt = '';
	switch (taskType) {
		case 'vul':
			if (vul0.length) {
				vulTxt = vul0.join('、');
			} else {
				vulTxt = `${
					vulType.length === Object.keys(VUL_TYPE_MAP).length
						? '所有漏洞类型'
						: vulType.map(id => VUL_TYPE_MAP[id]).join('、')
				}`;
			}
			return `下发Web漏洞自定义监测任务，资产名称：${job.note}，资产地址：${
				job.targetUrl
			}，监测内容：${vulTxt}，监测模式：仅高危，监测最大URL数：${
				taskSettings.collect.maxPage
			}，监测深度：${taskSettings.collect.depth}，${
				taskSettings.alert.enable ? '' : '未'
			}开启告警通知。`;
		case 'ssl':
			return `下发SSL安全自定义监测任务，资产名称：${job.note}，资产地址：${
				job.targetUrl
			}，监测内容：${
				taskSettings?.collect?.pluginCategories?.length ===
				Object.keys(SSL_CATEGORY_KEY_LABEL_MAP).length
					? '所有事件类型'
					: (taskSettings?.collect?.pluginCategories || [])
							.map(id => SSL_CATEGORY_KEY_LABEL_MAP[id])
							.join('、')
			}，${taskSettings.alert.enable ? '' : '未'}开启告警通知。`;
		case 'securityEvent':
			return `下发安全事件自定义监测任务，资产名称：${job.note}，资产地址：${
				job.targetUrl
			}，监测内容：${
				taskSettings?.collect?.plugins?.length ===
				Object.keys(SECURITY_EVENT_TYPE_MAP).length
					? '所有事件类型'
					: (taskSettings?.collect?.plugins || [])
							.map(id => SECURITY_EVENT_TYPE_MAP[id])
							.join('、')
			}，监测最大URL数：${taskSettings.collect.maxPage}，监测深度：${
				taskSettings.collect.depth
			}，${taskSettings.alert.enable ? '' : '未'}开启告警通知。`;
		case 'content':
			return `下发内容合规自定义监测任务，资产名称：${job.note}，资产地址：${
				job.targetUrl
			}，监测内容：${taskSettings?.collect?.plugins?.map(
				x => WARNING_CATEGORY_KEY_LABEL_MAP.content[x]
			)}，监测最大URL数：${taskSettings.collect.maxPage}，监测深度：${
				taskSettings.collect.depth
			}，${taskSettings.alert.enable ? '' : '未'}开启告警通知。`;
	}
};

export default {
	description: '自定义监测任务',
	type: 'JSON',
	args: {
		targetId: 'MongoID',
		taskType: 'String',
		isSpecialTask: 'Boolean',
		collect: 'JSON',
		alert: 'JSON',
		uid: 'MongoID',
		enable: 'Boolean',
		alertSettings: 'JSON',
		cookie: 'String',
		prelogin: 'JSON',
		customMonitorPage: 'UpdateOneJobCustomMonitorPageInput',
	},
	resolve: permissionCheckResolveDecorate({
		required: 'cloud-monitor\x01editTask',
		allMatchArgsBuilder(
			_source,
			args,
			{
				request: {
					auth: {
						credentials: { uid },
					},
				},
			}
		) {
			if (!args.uid) {
				args.uid = uid;
			}
		},
		selfOnlyArgsBuilder(
			_source,
			args,
			{
				request: {
					auth: {
						credentials: { uid },
					},
				},
			}
		) {
			args.uid = uid;
		},
	})(
		dealWithBalance(async (root, args, context) => {
			const ops = [];
			if (args.enable) {
				ops.push({
					key: `${args.taskType}ManualTask`,
					value: -1,
				});
			}

			return {
				ops,
				server: context.request.server,
				uid: args.uid,
			};
		})(
			async (
				root,
				{
					targetId,
					taskType,
					enable,
					isSpecialTask,
					collect,
					alert,
					uid,
					alertSettings,
					prelogin,
					customMonitorPage,
				},
				{ request }
			) => {
				if (!enable) {
					return false;
				}
				const {
					server: {
						app: {
							model: { Job },
						},
						methods: { createOrUpdateTask, getVulPluginList },
					},
				} = request;

				let idMapVulWarn;
				try {
					const vulWarnIds = await getVulPluginList();
					idMapVulWarn = vulWarnIds.reduce((res, item) => {
						res[item.id] = item.label;
						return res;
					}, {});
				} catch (error) {
					error.messageSuffix('自定义任务');
					request.log.error({ error }, error.detail);
					throw error;
				}

				let job;
				try {
					job = await Job.findOne({ uid, _id: targetId }).lean();
				} catch (err) {
					const error = errorCodes[
						'[01][自定义监测任务]查找任务mongo记录失败'
					].from(err);
					request.log.error({ error }, error.rawMessage);
					throw error;
				}

				if (!job) {
					const error = errorCodes['[01][自定义监测任务]没有找到对应mongo记录'];
					request.log.error({ targetId, taskType }, error.internalMessage);
					throw error;
				}

				const taskSettings = {
					collect,
					alert,
				};
				const triggerType = 'manual';
				try {
					await createOrUpdateTask({
						taskType,
						triggerType,
						body: {
							prelogin,
							alertSettings,
							taskSettings,
							customMonitorPage,
							jobId: targetId,
							enableMonitor: true,
							immediateExec: true,
						},
					});
				} catch (err) {
					const error = errorCodes['[01][自定义监测任务]添加任务失败'].from(
						err
					);
					request.log.error({ error }, error.rawMessage);
					throw error;
				}

				request.log.audit(
					{
						affects: [job.targetUrl],
						module: 'task',
						actionType: 'create',
						detail: detailBuilder({
							job,
							taskSettings,
							taskType,
							triggerType,
							idMapVulWarn,
						}),
						actionMessage: '下发监测任务',
					},
					`[${job.targetUrl}]${
						isSpecialTask ? '专项监测任务' : '自定义监测任务'
					}`
				);

				return {};
			}
		)
	),
};
